#include <stdio.h>
#include <stdlib.h>

#include <map>

typedef struct {
  void (*func)(void*);
} Base;

typedef struct {
  Base base;
  int data1;
} Derived1;

typedef struct {
  Base base;
  float data2;
} Derived2;

void base_func(void* obj) { printf("Base function called.\n"); }

void derived1_func(void* obj) {
  Derived1* p = (Derived1*)obj;
  printf("Derived1 function called with data1 = %d.\n", p->data1);
}

void derived2_func(void* obj) {
  Derived2* p = (Derived2*)obj;
  printf("Derived2 function called with data2 = %f.\n", p->data2);
}

int main() {
  std::map<int, Base*> objects;

  Derived1* d1 = (Derived1*)malloc(sizeof(Derived1));
  d1->base.func = &derived1_func;
  d1->data1 = 100;
  objects[1] = (Base*)d1;

  Derived2* d2 = (Derived2*)malloc(sizeof(Derived2));
  d2->base.func = &derived2_func;
  d2->data2 = 3.14f;
  objects[2] = (Base*)d2;

  for (auto it : objects) {
    int id = it.first;
    Base* obj = it.second;

    printf("Object with ID %d:\n", id);
    obj->func(obj);
  }

  free(d1);
  free(d2);

  return 0;
}
